package myzzyl.service.Impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import myzzyl.constants.ErrorConstants;
import myzzyl.domain.dto.RoomDto;
import myzzyl.domain.pojo.Bed;
import myzzyl.domain.pojo.Floor;
import myzzyl.domain.pojo.Room;
import myzzyl.domain.vo.BedVo;
import myzzyl.domain.vo.RoomTypeVo;
import myzzyl.domain.vo.RoomVo;
import myzzyl.exception.BusinessException;
import myzzyl.mapper.RoomMapper;
import myzzyl.service.BedService;
import myzzyl.service.FloorService;
import myzzyl.service.RoomService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
* @author 33249
* @description 针对表【room】的数据库操作Service实现
* @createDate 2025-08-07 20:07:33
*/
@Service
public class RoomServiceImpl extends ServiceImpl<RoomMapper, Room>
    implements RoomService {

    @Autowired
    private FloorService floorService;
    @Autowired
    private BedService bedService;

    /**
     * 获取楼层下的所有房间
     *
     * @param floorId 楼层id
     * @return 返回值
     */
    @Override
    public List<RoomVo> getAllByFloorId(Long floorId) {
        // 判断楼层是否存在
        Floor floor = floorService.getById(floorId);
        if (floor == null) {
            throw new BusinessException(ErrorConstants.FLOOR_IS_NOT_EXIST);
        }

        List<Room> roomList = lambdaQuery()
                .eq(floorId != null, Room::getFloorId, floorId)
                .list();

        // 转换为Vo对象返回
        List<RoomVo> roomVoList = roomList.stream().map(this::convertToVo).toList();
        return roomVoList;
    }


    /**
     * 获取房间详情
     *
     * @param id 房间id
     * @return 返回值
     */
    @Override
    public RoomVo getInfo(Long id) {
        // 查询房间是否存在
        Room room = getById(id);
        if (room == null) {
            throw new BusinessException(ErrorConstants.ROOM_IS_NOT_EXIST);
        }

        // 转换为Vo对象返回
        return convertToVo(room);
    }


    /**
     * 新增房间
     *
     * @param roomDto 房间表单包装类
     * @return 返回值
     */
    @Override
//    public Boolean add(RoomDto roomDto) {
//        // 校验房间编号是否为空
//        if(StrUtil.isBlank(roomDto.getCode())) {
//            throw new BusinessException(ErrorConstants.PARAMETER_IS_NOT_NULL);
//        }
//
//        // 根据房间编号查询房间
//        Room room = baseMapper.selectByCode(roomDto.getCode());
//        // 判断房间是否存在
//        if(room != null) {
//            // 判断逻辑字段是否为0
//            if(room.getIsDeleted() == 0) {
//                throw new BusinessException(ErrorConstants.ROOM_IS_ALREADY_EXIST);
//            }else {
//                // 更新逻辑删除字段
//                return baseMapper.updateRoom(room.getId());
//            }
//        }else {
//            // 为空，直接新增房间
//            room = new Room();
//            BeanUtils.copyProperties(roomDto, room);
//            room.setCreateTime(new Date());
//            room.setUpdateTime(new Date());
//            room.setCreateBy(1L);
//            room.setCreateBy(1L);
//
//            return save(room);
//        }
//    }
    public Boolean add(RoomDto roomDto) {
        // 查询要新增的房间是否已经存在
        if(lambdaQuery()
                .eq(StrUtil.isNotBlank(roomDto.getCode()), Room::getCode, roomDto.getCode())
                .exists()) {
            throw new BusinessException(ErrorConstants.ROOM_IS_ALREADY_EXIST);
        }

        //新增房间
        Room room = new Room();
        BeanUtils.copyProperties(roomDto, room);
        room.setCreateTime(new Date());
        room.setUpdateTime(new Date());
        room.setCreateBy(1L);
        room.setCreateBy(1L);

        return save(room);
    }


    /**
     * 编辑房间
     * @param roomDto 房间表单包装类
     * @return 返回值
     */
    @Override
    public Boolean edit(RoomDto roomDto) {
        if(lambdaQuery()
                .eq(StrUtil.isNotBlank(roomDto.getCode()), Room::getCode, roomDto.getCode())
                .ne(roomDto.getId() != null, Room::getId, roomDto.getId())
                .exists()) {
            throw new BusinessException(ErrorConstants.ROOM_IS_ALREADY_EXIST);
        }

        // 更新房间
        return lambdaUpdate()
                .set(StrUtil.isNotBlank(roomDto.getCode()), Room::getCode, roomDto.getCode())
                .set(StrUtil.isNotBlank(roomDto.getTypeName()), Room::getTypeName, roomDto.getTypeName())
                .set(roomDto.getSort() != null, Room::getSort, roomDto.getSort())
                .eq(Room::getId, roomDto.getId())
                .update();
    }


    /**
     * 删除房间
     * @param id 房间id
     * @return 返回值
     */
    @Override
    public Boolean deleteRoomById(Long id) {
        // 查询要删除的房间是否不存在
        if(!lambdaQuery().eq(id != null, Room::getId, id).exists()) {
            throw new BusinessException(ErrorConstants.ROOM_IS_NOT_EXIST);
        }

        // 更新逻辑删除字段
        return lambdaUpdate()
                .set(Room::getIsDeleted, null)
                .eq(Room::getId, id)
                .update();
    }

    private RoomVo convertToVo(Room room) {
        RoomVo roomVo = new RoomVo();
        BeanUtils.copyProperties(room, roomVo);

        // 获取房间下的所有床位数据
        List<BedVo> bedVoList = bedService.getAllByRoomId(room.getId());
        roomVo.setBedVoList(bedVoList);

        // 计算总床位数
        int totalBeds = bedVoList != null ? bedVoList.size() : 0;
        roomVo.setTotalBeds(totalBeds);

        // 查询入住了的床位数
        Long occupiedBeds = bedService.getOccupiedBeds(room.getId());
        roomVo.setOccupiedBeds(occupiedBeds.intValue());

        // 判断总床位数是否为0，避免除零异常
        if(totalBeds > 0) {
            roomVo.setOccupancyRate(occupiedBeds.doubleValue() / (double) totalBeds);
        }else {
            roomVo.setOccupancyRate(0.0);
        }
        return roomVo;
    }


    /**
     * 查询房型下的房间数
     * @param typeName 房型名称
     * @return 返回值
     */
    @Override
    public Long selectCountByRoomTypeId(String typeName) {
        return lambdaQuery()
                .eq(Room::getTypeName, typeName)
                .count();
    }
}




